package com.ndp.fb.walle.business.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.ndp.fb.model.AdSetStats;
import com.ndp.fb.mongo.api.AdGroupStatsHistoryMongoService;
import com.ndp.fb.mongo.api.AdSetStatsHistoryMongoService;
import com.ndp.fb.rdb.api.RuleScriptRdbService;
import com.ndp.fb.rdb.model.Pager;
import com.ndp.fb.rdb.model.rulescript.RuleScript;
import com.ndp.fb.rulescript.api.ScriptExecution;
import com.ndp.fb.rulescript.model.ScriptLoggerLevel;
import com.ndp.fb.rulescript.model.ScriptResult;
import com.ndp.fb.rulescript.model.ScriptRun;
import com.ndp.fb.util.DateFormatUtil;
import com.ndp.fb.util.ThreadPool;
import com.ndp.fb.walle.business.RuleScriptService;
import com.ndp.fb.walle.model.vo.rulescript.param.RuleScriptVoParam;
import com.ndp.fb.walle.model.vo.rulescript.result.ScriptRunVoResult;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;


/**
 * Created by sisi.chen on 15-6-25.
 */
@Component
public class RuleScriptServiceImpl implements RuleScriptService {
    @Reference
    private ScriptExecution scriptExecution;

    @Reference
    private RuleScriptRdbService ruleScriptRdbService;

    @Reference
    private AdGroupStatsHistoryMongoService adGroupStatsHistoryMongoService;

    @Reference
    private AdSetStatsHistoryMongoService adSetStatsHistoryMongoService;

    @Override
    public List<ScriptRunVoResult>
    test(String userId, RuleScriptVoParam ruleScriptVoParam, String timezoneId, String userid) {
        String adGroupId = null;
        String adSetId = null;
        if (0 == ruleScriptVoParam.getObjectiveType()) {
            adGroupId = ruleScriptVoParam.getObjectiveId();
        } else {
            adSetId = ruleScriptVoParam.getObjectiveId();
        }

        ScriptRun scriptRun = new ScriptRun(ruleScriptVoParam.getRuleName(), ruleScriptVoParam.getRuleScript(),
                ruleScriptVoParam.getRuleEngine(), adGroupId, adSetId,
                ruleScriptVoParam.getDataCycle(), ruleScriptVoParam.getSnapCycle(), true,
                DateFormatUtil.parseDateLong19(ruleScriptVoParam.getTiggerPointDate()),
                ScriptLoggerLevel.getScriptLoggerLevel(ruleScriptVoParam.getLogLevel()), ruleScriptVoParam.getIgnoreDataBuild());
        scriptRun.setUserId(userid);
        ScriptResult scriptResult = scriptExecution.execute(scriptRun);
        ScriptRunVoResult scriptRunVoResult = new ScriptRunVoResult(
                null == scriptResult.getExceptionMsg() ? null : scriptResult.getExceptionMsg().replace("<", "&lt;").replace(">", "&gt;").replace("\r\n", "</br>"),
                scriptResult.getResult(),
                null == scriptResult.getScriptLogger() ? null : scriptResult.getScriptLogger().format().replace("<", "&lt;").replace(">", "&gt;").replace("\r\n", "</br>"));
        List<ScriptRunVoResult> scriptRunVoResults = new ArrayList<>();
        scriptRunVoResults.add(scriptRunVoResult);
        return scriptRunVoResults;
    }

    @Override
    public Long save(String userId, RuleScript ruleScript) {
        List<RuleScript> versions = ruleScriptRdbService.findByUserIdAndRuleName(userId, ruleScript.getRuleName());

        //1、保存新的规则
        ruleScript.setUserId(userId);
        //设置版本
        ruleScript.setVersion(String.valueOf(versions.size() + 1));
        //设置创建时间
        ruleScript.setCreateTime(new Date());

        Long id = ruleScriptRdbService.save(ruleScript);

        if (!CollectionUtils.isEmpty(versions)){
            //2、将历史规则设置为is_run:0
            List<Long> ids = new ArrayList<>();
            for (RuleScript temp : versions){
                ids.add(temp.getId());
            }
            ruleScriptRdbService.updateIsRunByIdsIn(0, ids);
        }

        return id;
    }

    @Override
    public Pager<RuleScript> list(String userId, Integer offset, Integer limit) {
        return ruleScriptRdbService.page(userId, offset, limit);
    }

    @Override
    public Object detail(String userId, Long id) {
        RuleScript ruleScript = ruleScriptRdbService.findByUserIdAndId(userId, id);
        if (null == ruleScript){
            return null;
        }

        //根据user_id和rule_name查询版本信息
        List<RuleScript> versions = ruleScriptRdbService.findByUserIdAndRuleName(userId, ruleScript.getRuleName());
        Map<String, Object> results = new HashMap<>();
        results.put("rule", ruleScript);
        results.put("versions", versions);
        return results;
    }

    @Override
    public Object listSnapData(RuleScriptVoParam ruleScriptVoParam) {
        if (0 == ruleScriptVoParam.getObjectiveType()) {
           // 查询adgroup的快照数据
           return adGroupStatsHistoryMongoService.getAllSnap(Long.valueOf(ruleScriptVoParam.getObjectiveId()),
                    DateFormatUtil.parseDateLong10(ruleScriptVoParam.getTestStartDate()),
                    DateFormatUtil.parseDateLong10(ruleScriptVoParam.getTestEndDate()));
        } else {
            //查询adset的快照数据
            List<AdSetStats> allSnap = adSetStatsHistoryMongoService.getAllSnap(Long.valueOf(ruleScriptVoParam.getObjectiveId()),
                    DateFormatUtil.parseDateLong19(ruleScriptVoParam.getTestStartDate()),
                    DateFormatUtil.parseDateLong19(ruleScriptVoParam.getTestEndDate()));
            if(allSnap.size()>100)
                return  allSnap.subList(0,99);
            else
                return allSnap;
        }
    }

    @Override
    public String exportData(RuleScriptVoParam ruleScriptVoParam,String userid) {
        String adGroupId = null;
        String adSetId = null;
        if (0 == ruleScriptVoParam.getObjectiveType()) {
            adGroupId = ruleScriptVoParam.getObjectiveId();
        } else {
            adSetId = ruleScriptVoParam.getObjectiveId();
        }
        ScriptRun scriptRun = new ScriptRun(ruleScriptVoParam.getRuleName(), ruleScriptVoParam.getRuleScript(),
                ruleScriptVoParam.getRuleEngine(), adGroupId, adSetId,
                ruleScriptVoParam.getDataCycle(), ruleScriptVoParam.getSnapCycle(), true,
                DateFormatUtil.parseDateLong19(ruleScriptVoParam.getTiggerPointDate()),
                ScriptLoggerLevel.getScriptLoggerLevel(ruleScriptVoParam.getLogLevel()),
                ruleScriptVoParam.getIgnoreDataBuild());
        scriptRun.setUserId(userid);
        return scriptExecution.exportData(scriptRun);
    }

    @Override
    public void reCompile(final Long rulescriptId) {
        ThreadPool.execute(() -> scriptExecution.reCompile(rulescriptId));
    }

    @Override
    public void reRunLastSnap(final Long rulescriptId) {
        ThreadPool.execute(() -> scriptExecution.reRunLastSnap(rulescriptId));

    }
}
